<template>
  <div class="container">
    <el-table :data="tableData" border class="table" row-key="id">
      <el-table-column prop="menuName" label="菜单/按钮名称"></el-table-column>
      <el-table-column prop="path" label="对应路由"></el-table-column>
      <el-table-column prop="perms" label="权限码"></el-table-column>
      <el-table-column prop="icon" label="图标"></el-table-column>
      <el-table-column prop="type" label="类型">
        <template #default="scope">
          {{ scope.type === "0" ? "菜单" : "按钮" }}
        </template>
      </el-table-column>
      <el-table-column prop="orderNum" label="排序"></el-table-column>
      <el-table-column prop="createTime" label="创建时间"></el-table-column>
      <el-table-column label="操作" width="180">
        <template #default="scope">
          <el-button
            @click="handleAdd(scope.$index, scope.row)"
            icon="Plus"
            circle
          />
          <el-button
            @click="handleEdit(scope.$index, scope.row)"
            icon="Edit"
            circle
          />
          <el-button
            @click="handleDelete(scope.$index, scope.row)"
            icon="Delete"
            circle
          />
        </template>
      </el-table-column>
    </el-table>
  </div>

  <!-- 编辑弹出框 -->
  <el-dialog :title="title" v-model="editVisible" center @close="cancelEdit">
    <el-form :model="row" :rules="rules" ref="form" label-width="110px">
      <el-form-item prop="menuName" label="名称">
        <el-input v-model="row.menuName" placeholder="菜单/按钮名称"></el-input>
      </el-form-item>
      <el-form-item prop="parentId" label="父菜单">
        <el-select v-model="row.parentId" placeholder="上级部门">
          <el-option
            v-for="item in menuOptions"
            :key="item.id"
            :label="item.menuName"
            :value="item.id"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="path" label="对应路由">
        <el-input v-model="row.path" placeholder="对应路由"></el-input>
      </el-form-item>
      <el-form-item prop="perms" label="权限码">
        <el-input v-model="row.perms" placeholder="权限码"></el-input>
      </el-form-item>
      <el-form-item prop="icon" label="图标">
        <el-input v-model="row.icon" placeholder="图标"></el-input>
      </el-form-item>
      <el-form-item prop="type" label="类型">
        <el-select v-model="row.type" placeholder="请选择菜单类型">
          <el-option
            v-for="item in typeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="orderNum" label="排序">
        <el-input v-model="row.orderNum" placeholder="排序"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span>
        <el-button @click="cancelEdit">取 消</el-button>
        <el-button type="primary" @click="saveEdit">确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ElMessage, ElMessageBox } from "element-plus";
import { addMenu, deleteMenu, listMenu, updateMenu } from "@/api/menu";
import { reactive, ref } from "vue";

const rules = {
  menuName: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  parentId: [{ required: true, message: "请选择父菜单", trigger: "blur" }],
  type: [{ required: true, message: "请选菜单类型", trigger: "blur" }],
};

const query = reactive({
  pageNum: 1,
  pageSize: 10,
});

const tableData = ref([]);
const pageTotal = ref(0);
const title = ref("");
const editVisible = ref(false);
const row = reactive({});
const form = ref(null);
const menuOptions = ref([]);
const typeOptions = ref([
  { label: "菜单", value: "0" },
  { label: "按钮", value: "1" },
]);

// 获取菜单列表
const queryMenu = () => {
  listMenu(query).then((res) => {
    tableData.value = res.data.rows;
    pageTotal.value = res.data.total;
  });
};
// 查询操作
const handleSearch = () => {
  query.pageIndex = 1;
  queryMenu();
};
// 分页导航
const handlePageChange = (val) => {
  query.pageIndex = val;
  queryMenu();
};

// 删除操作
const handleDelete = (index, row) => {
  // 二次确认删除
  ElMessageBox.confirm("确定要删除吗？", "提示", {
    type: "warning",
    confirmButtonText: "确定",
    cancelButtonText: "取消",
  }).then(() => {
    deleteMenu(row.id).then(() => {
      ElMessage.success("删除成功");
      queryMenu();
    });
  });
};

// 显示添加窗口
const handleAdd = (index, row) => {
  row = {};

  menuOptions.value = menuTreeDataToArr(tableData.value);
  menuOptions.value.push({ id: 0, menuName: "无" });

  row.parentId = row.id;
  title.value = "添加菜单";
  editVisible.value = true;
};

// 显示修改窗口
const handleEdit = (index, row) => {
  menuOptions.value = menuTreeDataToArr(tableData.value, row.id);
  menuOptions.value.push({ id: 0, menuName: "无" });

  this.row = row;
  title.value = "编辑菜单";
  editVisible.value = true;
};

// 取消修改
const cancelEdit = () => {
  editVisible.value = false;
  queryMenu();
};

// 保存修改
const saveEdit = () => {
  form.value.validate((valid) => {
    if (valid) {
      if (title.value === "编辑菜单") {
        updateMenu(row).then(() => {
          ElMessage.success("更新成功");
          editVisible.value = false;
          queryMenu();
        });
      } else {
        addMenu(row).then(() => {
          ElMessage.success("添加成功");
          editVisible.value = false;
          queryMenu();
        });
      }
    }
  });
};

// 菜单树转数组
const menuTreeDataToArr = (data, id) => {
  const res = [];

  function dfs(tree) {
    const newTree = {
      id: tree.id,
      menuName: tree.menuName,
      parentId: tree.parentId,
    };
    res.push(newTree);
    if (tree.children) {
      for (const item of tree.children) {
        if (item.id === id) {
          break;
        }

        dfs(item);
      }
    }
  }

  for (const item of data) {
    if (item.id !== id) {
      dfs(item);
    }
  }
  return res;
};

queryMenu();
</script>
